package com.sunny.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

public class NioEchoServer {

    private static final int PORT = 8001;
    private static final int BUFFER_SIZE = 1024;

    public void listen(int port) throws IOException {

        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);

        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true){

            selector.select();

            Iterator<SelectionKey> iter = selector.selectedKeys().iterator();

            while (iter.hasNext()){

                SelectionKey key = iter.next();
                iter.remove();
                if(key.isAcceptable()){
                    // 接收到新请求
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel socketChannel = server.accept();
                    socketChannel.configureBlocking(false);
                    SelectionKey clientKey = socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
                    clientKey.attach(buffer);
                }else if(key.isReadable()){
                    //读就绪
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = (ByteBuffer) key.attachment();
                    socketChannel.read(buffer);
                }else if(key.isWritable()){
                    //写就绪
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = (ByteBuffer) key.attachment();
                    buffer.flip();
                    socketChannel.write(buffer);
                    buffer.compact();
                }

            }

        }

    }

    public static void main(String[] args) {

        NioEchoServer nioEchoServer = new NioEchoServer();
        try {
            nioEchoServer.listen(PORT);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}
